package com.example.xiaomiao.Util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import static com.example.xiaomiao.Util.MyConstants.TOKEN_CACHE_TTL;
import static com.example.xiaomiao.Util.MyConstants.TOKEN_KEY;

@Component
public class JwtUtil {
    private static final String secretKey = "GYMsuBYDxiaomaomiaomiaomiao"; // 替换为你的密钥

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    private static StringRedisTemplate stringRedisTemplate1;

    @PostConstruct
    public void init() {
        stringRedisTemplate1 = stringRedisTemplate;
    }

    // 生成 JWT 令牌
    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24)) // 设置过期时间为 1 天
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
    }

    // 解析 JWT 令牌
    public static Claims extractClaims(String token) {
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token)
                .getBody();
    }

    // 获取用户名
    public static String extractUsername(String token) {
        return extractClaims(token).getSubject();
    }

    // 检查令牌是否已过期
    public static boolean isTokenExpired(String token) {
        return extractClaims(token).getExpiration().before(new Date());
    }

    // 检查令牌是否将要过期
    public static boolean isTokenWillExpired(String token){
        return extractClaims(token).getExpiration().before(new Date(System.currentTimeMillis()+3 * 60 * 60 * 1000));
    }

    // 验证 JWT 令牌
    public static boolean validateToken(String token, String username) {
        return (username.equals(extractUsername(token)) && !isTokenExpired(token));
    }

    public static String getTokenFromCookie(HttpServletRequest request){
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("token".equals(cookie.getName())) {
                    return cookie.getValue();
                }
            }
        }
        return null;
    }

    public static void setTokenToCookieAndCache(HttpServletResponse response, String token, String id) {
        Cookie cookie = new Cookie("token", token);
        cookie.setPath("/");       // 适用于整个应用
        cookie.setMaxAge(1000 * 60 * 60 * 24);    // 1天有效期
        response.addCookie(cookie);
        stringRedisTemplate1.opsForValue().set(TOKEN_KEY + id,token, TOKEN_CACHE_TTL, TimeUnit.HOURS);
    }

    public static boolean checkUserSignalLogin(String token){
        String id = extractUsername(token);
        String login_token = stringRedisTemplate1.opsForValue().get(TOKEN_KEY + id);
        if(login_token == null)
            return true;
        return !token.equals(login_token);
    }
}

